package com.icez.base_util_library

import android.animation.LayoutTransition
import android.content.res.ColorStateList
import android.graphics.Bitmap
import android.graphics.Canvas
import android.graphics.Rect
import android.graphics.Typeface
import android.os.Build
import android.text.Spannable
import android.text.SpannableString
import android.text.TextPaint
import android.text.method.LinkMovementMethod
import android.text.style.ClickableSpan
import android.text.style.ImageSpan
import android.text.style.TextAppearanceSpan
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.LinearLayout
import android.widget.TextView
import androidx.annotation.RequiresApi
import java.util.HashMap

/**
 *  View工具类
 * @author icez
 */
class ViewUtil {
    companion object{
        val instance:ViewUtil by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED){
            ViewUtil()
        }
    }

    /**
     *  循环添加控件
     * @author icez
     * @param parentView 父控件
     * @param data 数据
     * @param itemViewId 子控件布局id
     * @param itemViewListener 子控件回调
     */
    public fun <T> forAddView(parentView:ViewGroup?,data:ArrayList<T>,itemViewId:Int?,itemViewListener:(itemView: View?,position: Int?,itemData:T?)->Unit?){
        parentView?.removeAllViews()
        data.forEachIndexed { index, t ->
            val itemView =
                itemViewId?.let { LayoutInflater.from(parentView?.context).inflate(it,null,false) }
            itemViewListener(itemView,index,t)
            parentView?.addView(itemView)
        }
    }

    /**
     *  坐标是否在rect区域中
     * @author icez
     * @param x 坐标x
     * @param y 坐标y
     * @param rect 区域
     */
    public fun coordInRect(x:Float,y:Float,rect: Rect):Boolean{
        return x >= rect.left && x <= rect.right && y >= rect.top && y <= rect.bottom
    }

    /**
     *  获取控件范围
     * @param view 控件
     */
    public fun getViewRect(view:View):Rect{
        val rect = Rect()
        view.getGlobalVisibleRect(rect)
        return rect
    }

    /**
     *  给布局添加改变动画
     * @param mViewGroup 控件
     * @param mDuration 动画时间
     * @param mTransitionType 动画类型
     */
    public fun layoutChangeAnima(mViewGroup:ViewGroup,mDuration:Long = 300,mTransitionType:Int = LayoutTransition.CHANGING){
        val transition = LayoutTransition()
        transition.setDuration(mDuration)
        transition.enableTransitionType(mTransitionType)
        mViewGroup.layoutTransition = transition
    }

    /**
     *  设置textview 样式
     * @param tv 控件
     * @param str 原文本
     * @param targetMap 需要改的字符和字符颜色
     * @param mDrawable 文本加图片
     * @param imgWidth 图片宽度
     * @param imgHeight 图片高度
     * @param imgGravity 图片位置
     * @param mImageToTextLeftAndRight 图片方向 0 左边  1 右边
     * @param isUnderline 是否下划线
     * @param familyMap 需要修改的字体样式
     * @param sizeMap 需要修改字体大小
     * @param styleMap 需要修改字体加粗 Typeface.NORMAL
     * @param tvClick 需要的字体点击事件
     *
     */
    fun setTvColor(
        tv: TextView?, str:String,
        targetMap: HashMap<String, Int>,
        mDrawable:Int = 0,
        imgWidth:Int = 0,
        imgHeight:Int = 0,
        imgGravity: Int = ImageSpan.ALIGN_CENTER,
        mImageToTextLeftAndRight:Int = 0,
        isUnderline:Boolean=false,
        familyMap: HashMap<String, String>? = null,
        styleMap: HashMap<String, Int>? = null,
        sizeMap: HashMap<String, Float>? = null,
        tvClick: ((tv: TextView, mStr:String) -> Unit)? = null){

        val spannableString = SpannableString(str)
        tv?.text = ""

        var mSize = tv?.textSize?:0f


        targetMap.entries.forEachIndexed { index, mutableEntry ->
            val targetStr = mutableEntry.key
            val color = mutableEntry.value
            var lsStr = str
            var isContains = lsStr.contains(targetStr)
            if(isContains){
                var start = 0
                var js = 0
                var end = targetStr.length

                while (lsStr.contains(targetStr)){
                    start = lsStr.indexOf(targetStr) + js

                    var style = 0
                    if(styleMap?.containsKey(targetStr)==true){
                        style = styleMap.get(targetStr)?.toInt()?: Typeface.NORMAL
                    }else{
                        style = Typeface.NORMAL
                    }

                    var family:String? = null
                    if(familyMap?.containsKey(targetStr)==true){
                        family = familyMap.get(targetStr)?.toString()?:null
                    }else{
                        family = null
                    }

                    if(sizeMap?.containsKey(targetStr)==true){
                        mSize = sizeMap.get(targetStr)?.toFloat()?:0f
                    }else{
                        mSize = 0f
                    }

                    val mTextAppearanceSpan = TextAppearanceSpan(family, style,mSize.toInt(),
                        ColorStateList.valueOf(color),null
                    )
                    spannableString.setSpan(mTextAppearanceSpan,start,start+end, Spannable.SPAN_INCLUSIVE_EXCLUSIVE)

                    if(tvClick!=null){
                        val clickableSpan = object : ClickableSpan() {
                            val mStr = str.substring(start,start+end)
                            override fun onClick(widget: View) {
                                LogUtil.E("点击："+mStr)
                                val tv = widget as TextView
                                if (tvClick != null) {
                                    tvClick(tv,mStr)
                                }
                            }
                            override fun updateDrawState(ds: TextPaint) {
                                ds.setUnderlineText(isUnderline)
                            }
                        }
                        spannableString.setSpan(clickableSpan,start,start+end, Spannable.SPAN_INCLUSIVE_EXCLUSIVE)
                    }

                    if((start+end)>=str.length){
                        break
                    }
                    lsStr = str.substring(start+end,str.length)
                    js = start + end
                }
            }

        }

        tv?.movementMethod = LinkMovementMethod.getInstance()
        if(mDrawable<=0){
            val drawable = tv?.context?.resources?.getDrawable(mDrawable,null)
            var iWidth = 0
            if(imgWidth==0){
                iWidth = drawable?.intrinsicWidth?:0
            }else{
                iWidth = imgWidth
            }
            var iHeight = 0
            if(imgHeight==0){
                iHeight = drawable?.intrinsicHeight?:0
            }else{
                iHeight = imgHeight
            }
            drawable?.setBounds(0,0,iWidth,iHeight)
            val imageSpan = drawable?.let { ImageSpan(it,imgGravity) }
            spannableString.setSpan(imageSpan,0,spannableString.length, SpannableString.SPAN_INCLUSIVE_EXCLUSIVE)

            when(mImageToTextLeftAndRight){
                0 -> {
                    tv?.append(spannableString)
                    tv?.append(str)
                }
                1 -> {
                    tv?.append(str)
                    tv?.append(spannableString)

                }
            }
        }else{
            tv?.append(spannableString)
        }
    }

    /**
     * 将一个未show的布局转换成bitmap
     */
    public fun viewToBitmap(view: View?): Bitmap {
        val bitmap =
            Bitmap.createBitmap(view?.width?:0, view?.height?:0, Bitmap.Config.ARGB_8888)
        view?.draw(Canvas(bitmap))
        return bitmap
    }


}